package com.youle.robots.swagger.config;

import com.google.common.base.Predicate;
import lombok.NonNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Predicates.or;
import static springfox.documentation.builders.PathSelectors.regex;


@Configuration
public class SwaggerConfig {

    private final SwaggerProperties properties;

    public SwaggerConfig(SwaggerProperties properties) {
        this.properties = properties;
    }

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage(properties.getBasePackage()))
                .paths(paths())
                .build()
                .globalOperationParameters(globalOperationParameters())
                .apiInfo(apiInfo());
    }

    /**
     * 放在头部的全局参数
     *
     * @return List<Parameter>
     */
    private List<Parameter> globalOperationParameters() {
        List<Parameter> pars = new ArrayList<>();
        Map<String, String> params = properties.getGlobalParameter();
        if (params.size() > 0) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                ParameterBuilder parameterBuilder = new ParameterBuilder();
                parameterBuilder.name(entry.getKey())
                        .description(entry.getValue())
                        .modelRef(new ModelRef("string"))
                        .parameterType("header")
                        .required(false)
                        .build();
                pars.add(parameterBuilder.build());
            }
        }
        return pars;
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(properties.getTitle())
                .description(properties.getDescription())
                .version(properties.getVersion())
                .termsOfServiceUrl("https://swagger.io/")
                .build();
    }

    @SuppressWarnings("unchecked")
    private Predicate paths() {
        @NonNull String[] urls = properties.getUrls();
        Predicate[] predicates = new Predicate[urls.length];
        for (int i = urls.length - 1; i >= 0; i--) {
            predicates[i] = regex(urls[i]);
        }
        return or(predicates);
    }
}
